package com.sne.common.exception;

import com.sne.common.entity.Result;
import com.sne.common.enums.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 统一异常处理
 * </p>
 *
 * @author fanghh
 * @since 2020/1/2
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(CustomException.class)
    public Result customerException(CustomException e) {
        log.error("全局异常信息 ex={}", e.getMessage(), e);
        return Result.failed(e.getMessage(), e);
    }

    /**
     * 校验 Exception
     *
     * @param exception 异常
     * @return Result
     */
    @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class})
    public Result bodyValidExceptionHandler(MethodArgumentNotValidException exception) {
        List<ObjectError> allErrors = exception.getBindingResult().getAllErrors();
        String data = allErrors.stream().map(DefaultMessageSourceResolvable::getDefaultMessage)
                .collect(Collectors.joining(","));
        log.error(data);
        return Result.restResult(ResultCode.PARAM_INVALID, data);
    }

    @ExceptionHandler(BadCredentialsException.class)
    public Result badCredentialsExceptionHandler(BadCredentialsException e) {
        log.error("全局异常信息 ex={}", e.getMessage(),e);
        return Result.restResult(ResultCode.UNAUTHORIZED, "用户名或密码不正确");
    }

    @ExceptionHandler(AccessDeniedException.class)
    public Result accessDeniedExceptionHandler(AccessDeniedException e){
        log.error("全局异常信息 ex={}", e.getMessage(),e);
        String message = e.getMessage();
        return Result.restResult(ResultCode.FORBIDDEN, message);
    }


    /**
     * 全局异常.
     *
     * @param e 异常
     * @return Result
     */
    @ExceptionHandler({Exception.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result exception(Exception e) {
        log.error("全局异常信息 ex={}", e.getMessage(), e);
        return Result.failed(e.getMessage(), e);
    }
}
